#ifndef __LCD_INIT_H
#define __LCD_INIT_H

#include "stm32f1xx.h"
//#include "spi.h"
#include "tim.h"

/* -------------------------------------------- LCD配置参数 -------------------------------------------- */

/* 定义是否使用LCD的CS引脚 */
#define USE_LCD_CS 1            /* 1:使用CS引脚  0:不使用CS引脚 */

/* 定义是否使用硬件SPI */
#define USE_HARDWARE_SPI 0      /* 1:使用硬件SPI  0:使用软件模拟SPI */

/* 定义是否使用PWM控制背光 */
#define USE_PWM_BLK 1           /* 1:使用PWM控制背光  0:使用普通GPIO控制背光 */

#if USE_HARDWARE_SPI
/* 定义硬件SPI句柄 */
extern SPI_HandleTypeDef hspi2;
#endif

/* LCD显示屏尺寸 */
#define LCD_W 240  /* LCD显示屏的宽度，单位为像素 */
#define LCD_H 240  /* LCD显示屏的高度，单位为像素 */

/* -------------------------------------------- LCD引脚定义 -------------------------------------------- */

/* SCL引脚定义 */
#define LCD_SCL_GPIO_PORT               GPIOC                                         /* SCL=SCLK */
#define LCD_SCL_GPIO_PIN                GPIO_PIN_8
#define LCD_SCL_GPIO_CLK_ENABLE()       do{ __HAL_RCC_GPIOC_CLK_ENABLE(); }while(0)   /* 所在IO口时钟使能 */

/* SDA引脚定义 */
#define LCD_SDA_GPIO_PORT               GPIOC
#define LCD_SDA_GPIO_PIN                GPIO_PIN_9                                    /* SDA=MOSI */
#define LCD_SDA_GPIO_CLK_ENABLE()       do{ __HAL_RCC_GPIOC_CLK_ENABLE(); }while(0)   /* 所在IO口时钟使能 */

/* RES引脚定义 */
#define LCD_RES_GPIO_PORT               GPIOC
#define LCD_RES_GPIO_PIN                GPIO_PIN_10
#define LCD_RES_GPIO_CLK_ENABLE()       do{ __HAL_RCC_GPIOC_CLK_ENABLE(); }while(0)   /* 所在IO口时钟使能 */

/* DC引脚定义 */
#define LCD_DC_GPIO_PORT                GPIOB
#define LCD_DC_GPIO_PIN                 GPIO_PIN_7
#define LCD_DC_GPIO_CLK_ENABLE()        do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)   /* 所在IO口时钟使能 */

#if USE_LCD_CS
/* CS引脚定义 */
#define LCD_CS_GPIO_PORT                GPIOB
#define LCD_CS_GPIO_PIN                 GPIO_PIN_8
#define LCD_CS_GPIO_CLK_ENABLE()        do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)   /* 所在IO口时钟使能 */
#endif

/* BLK引脚定义 */
#define LCD_BLK_GPIO_PORT               GPIOB
#define LCD_BLK_GPIO_PIN                GPIO_PIN_11
#define LCD_BLK_GPIO_CLK_ENABLE()       do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)   /* 所在IO口时钟使能 */

#if USE_PWM_BLK
/* -------------------------------------------- BLK PWM定时器定义 -------------------------------------------- */

/* TIM2定时器 */
#define LCD_BLK_TIMX                    TIM2
#define LCD_BLK_TIMX_CLK_ENABLE()       do{ __HAL_RCC_TIM2_CLK_ENABLE(); }while(0)

/* 通道定义 */
#define LCD_BLK_TIMX_CHY                TIM_CHANNEL_4

/* AFIO重映射宏定义 */
/* 注意：使用定时器时需要检查引脚是否需要重映射 */
#define LCD_BLK_TIMX_REMAP()            __HAL_AFIO_REMAP_TIM2_PARTIAL_2()    /* TIM2部分重映射2，将CH4映射到PB11 */

/* -------------------------------------------- 全局变量声明 ---------------------------------------------- */

extern TIM_HandleTypeDef g_lcd_blk_tim_handler;         /* 定时器句柄 */
extern TIM_OC_InitTypeDef g_lcd_blk_tim_oc_handler;     /* 定时器通道句柄 */
#endif

/* -------------------------------------------- LCD控制宏定义 -------------------------------------------- */

/* LCD 端口控制函数定义 - 利用操作寄存器的方式控制IO引脚提高屏幕的刷新率 */
#define LCD_SCL(x)      LCD_SCL_GPIO_PORT->BSRR = (x) ? LCD_SCL_GPIO_PIN : ((uint32_t)LCD_SCL_GPIO_PIN << 16)   /* 设置SCL引脚 */
#define LCD_SDA(x)      LCD_SDA_GPIO_PORT->BSRR = (x) ? LCD_SDA_GPIO_PIN : ((uint32_t)LCD_SDA_GPIO_PIN << 16)   /* 设置SDA引脚 */
#define LCD_RES(x)      LCD_RES_GPIO_PORT->BSRR = (x) ? LCD_RES_GPIO_PIN : ((uint32_t)LCD_RES_GPIO_PIN << 16)   /* 设置RES引脚 */
#define LCD_DC(x)       LCD_DC_GPIO_PORT->BSRR = (x) ? LCD_DC_GPIO_PIN : ((uint32_t)LCD_DC_GPIO_PIN << 16)      /* 设置DC引脚 */

#if USE_LCD_CS
#define LCD_CS(x)       LCD_CS_GPIO_PORT->BSRR = (x) ? LCD_CS_GPIO_PIN : ((uint32_t)LCD_CS_GPIO_PIN << 16)      /* 设置CS引脚 */
#else
#define LCD_CS(x)       /* CS引脚未使用 */
#endif

#if USE_PWM_BLK
#define LCD_BLK(x)      LCD_SetBacklight((x) ? 100 : 0)   /* 设置BLK引脚 */
#else
#define LCD_BLK(x)      LCD_BLK_GPIO_PORT->BSRR = (x) ? LCD_BLK_GPIO_PIN : ((uint32_t)LCD_BLK_GPIO_PIN << 16)   /* 设置BLK引脚 */
#endif

/* -------------------------------------------- 函数声明 ------------------------------------------------ */

/* 显示控制函数 */
void LCD_SetBacklight(uint8_t brightness);                                          /* 设置LCD背光亮度(0-100) */
void LCD_SetDirection(uint8_t direction);                                           /* 设置LCD显示方向 */
uint8_t LCD_GetDirection(void);                                                     /* 获取当前LCD显示方向 */

/* 底层驱动函数 */
void LCD_GPIO_Init(void);                                                           /* 初始化GPIO */
#if USE_PWM_BLK
void LCD_BLK_PWM_Init(uint16_t arr, uint16_t psc);                                  /* 初始化BLK PWM定时器 */
#endif
void LCD_Writ_Bus(uint8_t dat);                                                     /* 模拟SPI时序 */
void LCD_WR_DATA8(uint8_t dat);                                                     /* 写入一个字节 */
void LCD_WR_DATA(uint16_t dat);                                                     /* 写入两个字节 */
void LCD_WR_REG(uint8_t dat);                                                       /* 写入一个指令 */
void LCD_Address_Set(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);           /* 设置坐标函数 */
void LCD_Init(void);                                                                /* LCD初始化 */

#endif
